package service

import (
	pb "e-commerce/services/product-service/api/pb"
	"e-commerce/services/product-service/internal/cache"
	"e-commerce/services/product-service/internal/repository"
	"log"
)

type ProductService struct {
	Repo  *repository.ProductRepository
	Cache *cache.RedisCache
}

func (s *ProductService) GetProductByID(pbid string) (*pb.Product, error) {
	// 先尝试从缓存获取
	product, err := s.Cache.GetProduct(pbid)
	if err == nil {
		return product, nil
	}

	// 从数据库获取
	product, err = s.Repo.FindByID(pbid)
	if err != nil {
		return nil, err
	}

	// 缓存到 Redis
	err = s.Cache.SetProduct(pbid, product)
	if err != nil {
		log.Printf("缓存失败: %v", err)
	}

	return product, nil
}

func (s *ProductService) CreateProduct(product *pb.Product) (string, error) {
	pbid, err := s.Repo.Create(product)
	if err != nil {
		return "", err
	}

	// 缓存到 Redis
	err = s.Cache.SetProduct(pbid, product)
	if err != nil {
		log.Printf("缓存失败: %v", err)
	}

	return pbid, nil
}

func (s *ProductService) UpdateProduct(pbid string, product *pb.Product) error {
	err := s.Repo.Update(pbid, product)
	if err != nil {
		return err
	}

	// 缓存到 Redis
	err = s.Cache.SetProduct(pbid, product)
	if err != nil {
		log.Printf("缓存失败: %v", err)
	}

	return nil
}

func (s *ProductService) DeleteProduct(pbid string) error {
	err := s.Repo.Delete(pbid)
	if err != nil {
		return err
	}

	// 从 Redis 删除
	err = s.Cache.DeleteProduct(pbid)
	if err != nil {
		log.Printf("缓存删除失败: %v", err)
	}

	return nil
}

func (s *ProductService) ListProducts(category string) ([]*pb.Product, error) {
	// 先从缓存获取
	products, err := s.Cache.GetProducts(category)
	if err == nil {
		log.Printf("从缓存获取商品成功，数量: %d", len(products))
		return products, nil
	}

	// 从数据库获取
	products, err = s.Repo.FindByCategory(category)
	if err != nil {
		log.Printf("从数据库获取商品失败: %v", err)
		return nil, err
	}
	log.Printf("从数据库获取商品成功，数量: %d", len(products))
	// 缓存到 Redis
	err = s.Cache.SetProducts(category, products)
	if err != nil {
		log.Printf("缓存失败: %v", err)
	}

	return products, nil
}

// 根据配置文件初始化productService
func NewProductService(path string) *ProductService {
	repo := repository.NewMongoRepository(path)
	cache := cache.NewRedisCache(path)
	return &ProductService{Repo: repo, Cache: cache}
}
